package cn.jja8.config.tool.work.obj;

import cn.jja8.config.tool.work.obj.arrays.KeepArrays;
import cn.jja8.config.tool.work.obj.common.CommonKeepManager;
import cn.jja8.config.tool.work.obj.parameterized.ParameterizedKeepManager;
import cn.jja8.config.tool.work.obj.parameterized.TypeKeep;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

public class ObjKeepManager {
    private final CommonKeepManager commonKeepManager = new CommonKeepManager();
    private final ParameterizedKeepManager parameterizedKeepManager = new ParameterizedKeepManager(this);
    private final KeepArrays keepArrays = new KeepArrays(this);

    public KeepArrays getKeepArrays() {
        return keepArrays;
    }

    public CommonKeepManager getCommonKeepManager() {
        return commonKeepManager;
    }

    public ParameterizedKeepManager getParameterizedKeepManager() {
        return parameterizedKeepManager;
    }

    /**
     * 将con转换成自己提供的对象
     * */
    public Object in(Object con, Type type){
        try {
            if (type instanceof ParameterizedType){
                return parameterizedKeepManager.getNoNull((Class)((ParameterizedType) type).getRawType())
                        .in(con, Arrays.stream(((ParameterizedType) type)
                                        .getActualTypeArguments())
                                .map(m->new TypeKeep(this,m))
                                .toArray(TypeKeep[]::new));
            }
            if (type instanceof Class){
                Class tClass = (Class) type;
                if (Object[].class.isAssignableFrom(tClass)){
                     return keepArrays.in((List) con,tClass);
                }
                return commonKeepManager.getNoNull(tClass).in(con);
            }
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        throw new Error("不支持的类型"+type);
    }

    /**
     * 将自己提供的对象转换成con
     * */
    public Object out(Object v, Type type){
        try {
            if (type instanceof ParameterizedType){
                return parameterizedKeepManager.getNoNull((Class)((ParameterizedType) type).getRawType())
                        .out(v, Arrays.stream(((ParameterizedType) type)
                                        .getActualTypeArguments())
                                .map(m->new TypeKeep(this,m))
                                .toArray(TypeKeep[]::new));
            }
            if (type instanceof Class){
                Class tClass = (Class) type;
                if (Object[].class.isAssignableFrom(tClass)){
                    return keepArrays.out((Object[]) v,tClass);
                }
                return commonKeepManager.getNoNull(tClass).out(v);
            }
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        throw new Error("不支持的类型"+type);
    }
}
